//
// Created by wangjunjun on 2024/3/20.
//

#include "httpresquest.h"
#include "json.h"
#include "value.h"
#include "writer.h"
#include <iostream>
std::shared_ptr<HttpResquest> HttpResquest::m_InStance = nullptr;
std::once_flag HttpResquest::m_flag;
HttpResquest::HttpResquest(){

}
HttpResquest::~HttpResquest(){
 //  curl_easy_cleanup();
}

std::shared_ptr<HttpResquest> HttpResquest::GetInStance(){
    std::call_once(m_flag, [](){
       m_InStance= std::shared_ptr<HttpResquest>(new HttpResquest(),
               [](HttpResquest *ptr){delete ptr;});
    });
    return  m_InStance;
}

size_t HttpResquest::WriteCallback(void* contents, size_t size, size_t nmemb, std::string* response){
    size_t totalSize= size * nmemb;
    response->append(static_cast<char *>(contents), totalSize);
    return totalSize;
}
bool HttpResquest::SendRequest(const std::string& url, const RequestBody& requestBody, ResponseBody& response) {
    CURL* curl = curl_easy_init();
    if (!curl) {
        // 记录错误并返回 false
        LOG_ERROR("Failed to initialize libcurl.");
        return false;
    }

    struct curl_slist* headers = nullptr;
    try {
        headers = curl_slist_append(headers, "Content-Type: application/json");
        if (!headers) {
            // 记录错误并返回 false
            LOG_ERROR("Failed to set up headers.");
            curl_easy_cleanup(curl);
            return false;
        }

        std::string reqBodyStr;
        {
            Json::Value param;
            Json::FastWriter writer;
            param["robotSn"] = requestBody.robotSn;
            param["dateTime"] = requestBody.dateTime;
            param["position"] = requestBody.position;
            param["msg"] = requestBody.msg;
            reqBodyStr = writer.write(param);
        }

        std::string resBody;
        CURLcode res;
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
        curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, reqBodyStr.c_str());
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &resBody);

        res = curl_easy_perform(curl);
        if (res != CURLE_OK) {
            // 如果请求失败，记录错误并返回 false
            LOG_ERROR("Failed to send HTTP request: {}", curl_easy_strerror(res));
            curl_slist_free_all(headers);
            curl_easy_cleanup(curl);
            return false;
        }

        // Parse response
        Json::Reader reader;
        Json::Value respJson;
        if (!reader.parse(resBody, respJson)) {
            // 如果 JSON 解析失败，记录错误并返回 false
            LOG_ERROR("Unable to parse JSON response.");
            curl_slist_free_all(headers);
            curl_easy_cleanup(curl);
            return false;
        }

        response.code = respJson["code"].asInt();
        response.url = respJson["url"].asString();
        curl_slist_free_all(headers);
        curl_easy_cleanup(curl);
        return true; // 请求成功，返回 true
    } catch (...) {
        // 任何异常发生时清理资源并返回 false
        curl_slist_free_all(headers);
        curl_easy_cleanup(curl);
        return false;
    }
}